package com.allwees.bs.c.module.order.context.listener;

import com.allwees.bs.c.module.ops.service.CashActiveDefUseService;
import com.allwees.bs.c.module.ops.service.PromoUseService;
import com.allwees.bs.c.module.ops.service.UserCouponService;
import com.allwees.bs.c.module.order.context.event.OrderPayedEvent;
import com.allwees.bs.c.module.order.dto.OrderDTO;
import com.allwees.bs.c.module.order.dto.OrderItemDTO;
import com.allwees.bs.c.module.order.dto.ProductSnapDTO;
import com.allwees.bs.c.module.order.service.CartService;
import com.allwees.bs.c.module.order.service.IOrderItemService;
import com.allwees.bs.c.module.order.service.IOrderService;
import com.allwees.bs.c.module.product.service.FreeGiftRecordService;
import com.allwees.bs.c.module.product.service.ProductService;
import com.allwees.bs.core.model.constant.CacheName;
import com.allwees.core.cache.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;

import java.math.BigDecimal;
import java.util.List;

/**
 * 订单支付成功Listener
 *
 * @author yangylsky
 * @since 2019-08-17
 */
@Slf4j
@Component
public class OrderPayedListener {

    @Autowired
    private CartService cartService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private CashActiveDefUseService cashActiveDefUseService;
    @Autowired
    private UserCouponService userCouponService;
    @Autowired
    private PromoUseService promoUseService;

    @Autowired
    private FreeGiftRecordService freeGiftRecordService;

    @Autowired
    private ProductService productService;

    @Autowired
    private IOrderItemService orderItemService;

//    @Autowired
//    private  OrderLogActionUtil orderLogActionUtil;



    @Async
    @TransactionalEventListener
    public void onOrderPayed(OrderPayedEvent event) {

        OrderDTO order = (OrderDTO) event.getSource();
        log.info("receive order payed event[orderNo:{}]", order.getNo());

        orderService.check4UserFirstPayedOrder(order);

        clearUserCart(order.getUserUuid());

        useUserCoupon(order.getUserCouponUuid(), order.getUserPromoLogUuid());
        useUserCash(order.getUserUuid(), order.getUuid(), order.getAmtCash());
        freeGiftProduct(order);
        //针对限购商品记录已购买数量
        doBuyNumLimit(order.getUserUuid(),order.getItems());
        /**
         * 给用户发送订单确认邮件
         */
        orderService.sendOrderConfirmEmail(order.getUuid());

//        orderLogActionUtil.logAction(order,EActionType.ORDER_PAY);
    }

    /**
     * 限购次数
     * @param userUuid
     * @param orderItemDTOS
     */
    private void doBuyNumLimit(String userUuid,List<OrderItemDTO> orderItemDTOS) {
        for(OrderItemDTO orderItemDTO : orderItemDTOS) {
            Integer numPerUser = RedisUtil.hget(CacheName.PROD_PRODUCT_MODEL_BY_UUID, orderItemDTO.getProductUuid());
            if (numPerUser == null || numPerUser == 0) {
                return;
            }
            Integer buyedNum = RedisUtil.hget(CacheName.USER_BUY_PRODUCT_NUM, userUuid + ":" + orderItemDTO.getProductUuid());
            log.info("======checkout=======userUuid:{},has buyed num:{}, productUuid:{}", userUuid, buyedNum, orderItemDTO.getProductUuid());
            if (buyedNum == null) {
                buyedNum = 0;
            }
            buyedNum = buyedNum + orderItemDTO.getQuantity();
            RedisUtil.hset(CacheName.USER_BUY_PRODUCT_NUM, userUuid + ":" + orderItemDTO.getProductUuid(), buyedNum);
        }
    }

    private void clearUserCart(String userUuid) {
        cartService.clearUserCart(userUuid);
    }

    private void useUserCoupon(String userCouponUuid, String userPromoLogUuid) {
        if (StringUtils.isNotBlank(userCouponUuid)) {
            userCouponService.completed(userCouponUuid);
        }
        if (StringUtils.isNotBlank(userPromoLogUuid)) {
            promoUseService.completed(userPromoLogUuid);
        }
    }

    private  void freeGiftProduct(OrderDTO order ) {
        List<OrderItemDTO>  orderItemDTOList = order.getItems();
        orderItemDTOList.forEach(orderItemDTO -> {
            ProductSnapDTO productSnapDTO = orderItemDTO.getProduct();
            if (productSnapDTO.getFreeGift()) {
                freeGiftRecordService.applied(order.getUserUuid(),productSnapDTO.getUuid());
            }
        });
    }

    private void useUserCash(String userUuid, String orderUuid, BigDecimal userCashAmt) {
        if (userCashAmt == null || BigDecimal.ZERO.compareTo(userCashAmt) >= 0) {
            return;
        }
        cashActiveDefUseService.use(userUuid, orderUuid, userCashAmt);
    }
}
